/*
 * Grafo.h
 *
 *  Created on: 16/10/2012
 *      Author: vagner
 */

#ifndef GRAFO_H_
#define GRAFO_H_
#include <vector>
#include "MyMatrix.h"
#include <cmath>
#define N_ATENDIDO -1
#define MEDIANA -2

namespace tp2cn {

typedef struct {
	int idVertice; //ID único para cada vertice;
	double coorX; //Coordenada X do ponto
	double coorY; //Coordenada Y do ponto
	int capacidade; //Capacidade de atendimento de um vertice
	int demanda; //Capacidade demandada de um ponto.
	int numeroFormigas; //Número de formigas que visitaram o vértice;
	int atendidoPor; // Identificador da mediana que atende ao vértice, caso o vértice não seja mediana
} Vertice;

typedef std::vector<Vertice> Vertices;
typedef MyMatrix MatrizDistancia;

class Grafo {
private:
	Vertices pVertice;
	MatrizDistancia* MD;
	int numVertices;
	int minCapacidade, maxCapacidade;
	int minDemanda, maxDemanda;

public:
	Grafo();
	Grafo(int numVertices);
	void insereVertice(const Vertice& v);
	void insereVerticeNaPosicao(const Vertice& v, int posicao);
	void calculaMatrizDistancia(void);
	//Calcula a distancia do vertice 'idVertice' com relação aos demais vértices do grafo
	void calculaDistanciaVertice(int idVertice);
	void showVertices(void) const;
	void showMatrizDistancia(void) const;
	int getCapacidade(int idVertice);
	void setCapacidade(int idVertice, int capacidade);
	int getDemanda(int idVertice);
	int getNumVertices();
	double getDistancia(int vertice_1, int vertice_2);
	int getMinDemanda();
	int getMaxDemanda();
	int getMinCapacidade();
	int getMaxCapacidade();
	Vertice getPontoMedio();
	//Aumenta o número de visitas a um vertice
	void defineNovaVisita(int idVertice);
	Vertice getVertice(int idVertce);
	//Retorna bool se o vertice já é atendido por alguma mediana;
	bool verticeAtendido(int idVertice);
	//Retorna o identificador da mediana que atendo ao vertice
	int getMediana(int idVertice);
	void setAtendimento(int idVertice, int idMediana);
	virtual ~Grafo();

	long double distanciaEntreVertices(Vertice& v1, Vertice& v2) {
		long double distancia;
		if (v1.idVertice == v2.idVertice) {
			distancia = 0.0;
		} else {
			distancia = long(
					std::sqrt(
							std::pow(v2.coorX - v1.coorX, 2.0)
									+ std::pow(v2.coorY - v1.coorY, 2.0)));
		}
		return distancia;
	}
};

} /* namespace tp2cn */
#endif /* GRAFO_H_ */
